package com.jastar.android.game.gobang;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.jastar.android.game.gobang.enums.GameMode;

public class ChessBoardView extends View {
    private static final int BOARD_SIZE = 15; // 棋盘行列数

    private AIPlayer aiPlayer;
    private GameMode gameMode;
    private boolean gameover = false;

    private int cellSize;    // 格子大小
    private int[][] board;   // 棋盘状态
    private int currentPlayer = 1; // 当前玩家（1=黑棋，2=白棋）
    private Paint gridPaint, blackPaint, whitePaint;
    private EventListener touchListener;
    private EventListener gameEndListener;

    private int cursorX = BOARD_SIZE / 2;
    private int cursorY = BOARD_SIZE / 2;
    private Paint cursorPaint;

    public void gameover() {
        this.gameover = true;
    }

    public void setGameMode(GameMode gameMode, boolean isMaster) {
        this.aiPlayer = new AIPlayer();
        if (isMaster) this.aiPlayer.setMaster(true);
        this.gameMode = gameMode;
    }

    public ChessBoardView(Context context) {
        super(context);
        init();
    }

    public ChessBoardView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        gridPaint = new Paint();
        gridPaint.setColor(Color.BLACK);
        gridPaint.setStrokeWidth(2);

        blackPaint = new Paint();
        blackPaint.setColor(Color.BLACK);
        blackPaint.setStyle(Paint.Style.FILL);

        whitePaint = new Paint();
        whitePaint.setColor(Color.WHITE);
        whitePaint.setStyle(Paint.Style.FILL);

        cursorPaint = new Paint();
        cursorPaint.setStyle(Paint.Style.STROKE);
        cursorPaint.setStrokeWidth(3);

        board = new int[BOARD_SIZE][BOARD_SIZE];
    }

    // AI接口
    private final AIPlayer.BoardState boardState = new AIPlayer.BoardState() {
        @Override
        public int[][] getBoard() {
            return board;
        }

        @Override
        public boolean isValidMove(int row, int col) {
            return board[row][col] == 0;
        }
    };

    /**
     * 自定义自身尺寸，保证正方形和自适应宽高
     * View显示的三个步骤：
     * onMeasure()  第一步，确定View的尺寸
     * onLayout()   第二步，确定子View的位置
     * onDraw()     第三步，实际绘制
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
        cellSize = size / BOARD_SIZE;
        setMeasuredDimension(size, size);
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        drawGrid(canvas);
        drawPieces(canvas);
        drawCursor(canvas);
    }

    private void drawGrid(Canvas canvas) {
        for (int i = 0; i < BOARD_SIZE; i++) {
            float offset = cellSize / 2f;
            float pos = i * cellSize;
            // 画横线
            canvas.drawLine(offset, pos + offset, BOARD_SIZE * cellSize - offset, pos + offset, gridPaint);
            // 画竖线
            canvas.drawLine(pos + offset, offset, pos + offset, BOARD_SIZE * cellSize - offset, gridPaint);
        }
    }

    private void drawPieces(Canvas canvas) {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (board[i][j] != 0) {
                    float cx = i * cellSize + cellSize / 2f;
                    float cy = j * cellSize + cellSize / 2f;
                    canvas.drawCircle(cx, cy, cellSize / 2f - 10, board[i][j] == 1 ? blackPaint : whitePaint);
                }
            }
        }
    }

    private void drawCursor(Canvas canvas) {
        float left = cursorX * cellSize;
        float top = cursorY * cellSize;
        float right = (cursorX + 1) * cellSize;
        float bottom = (cursorY + 1) * cellSize;

        cursorPaint.setColor(getCurrentPlayer() == 1 ? Color.BLACK : Color.WHITE);
        canvas.drawRect(left, top, right, bottom, cursorPaint);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (isCurrentAI()) return super.onKeyDown(keyCode, event);
        int newX = cursorX;
        int newY = cursorY;

        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_LEFT:
                newX = Math.max(0, cursorX - 1);
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                newX = Math.min(14, cursorX + 1);
                break;
            case KeyEvent.KEYCODE_DPAD_UP:
                newY = Math.max(0, cursorY - 1);
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
                newY = Math.min(14, cursorY + 1);
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:  //一般遥控的确认键
            case KeyEvent.KEYCODE_BUTTON_1:     //某些设备的确认键
                handDown(cursorX, cursorY);
                return true;
            default:
                return super.onKeyDown(keyCode, event);
        }

        if (newX != cursorX || newY != cursorY) {
            cursorX = newX;
            cursorY = newY;
            invalidate();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    // 处理触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (isCurrentAI()) return super.onTouchEvent(event);
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            int x = (int) (event.getX() / cellSize);
            int y = (int) (event.getY() / cellSize);
            if (handDown(x, y)) return true;
        }
        return super.onTouchEvent(event);
    }

    /** 当前是AI的回合 */
    private boolean isCurrentAI() {
        return !gameover && gameMode == GameMode.VS_AI && currentPlayer == 2;
    }

    //落子逻辑
    private boolean handDown(int x, int y) {
        if (gameover) return false;
        if (isValidMove(x, y)) {
            board[x][y] = currentPlayer;
            if (checkWin(x, y)) {
                gameover = true;
                if (gameEndListener != null) {
                    gameEndListener.onEvent(currentPlayer);
                }
            } else {
                currentPlayer = currentPlayer == 1 ? 2 : 1;
                touchListener.onEvent(currentPlayer);
                if (isCurrentAI()) aiMove();
            }
            invalidate();
            return true;
        }
        return false;
    }

    private void aiMove() {
        int[] move = aiPlayer.makeMove(boardState);
        if (move[0] != -1) {
            postDelayed(() -> handDown(move[0], move[1]), 1000); //添加延时动画
        }
    }

    // 检查落子有效性
    private boolean isValidMove(int row, int col) {
        return row >= 0 && row < BOARD_SIZE && col >= 0 && col < BOARD_SIZE && board[row][col] == 0;
    }

    // 检查胜负（核心算法）
    private boolean checkWin(int row, int col) {
        int[][] directions = {{1, 0}, {0, 1}, {1, 1}, {1, -1}}; // 四个方向
        int player = board[row][col];

        for (int[] dir : directions) {
            int count = 1;
            // 正向检查
            int r = row + dir[0];
            int c = col + dir[1];
            while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {
                count++;
                r += dir[0];
                c += dir[1];
            }
            // 反向检查
            r = row - dir[0];
            c = col - dir[1];
            while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == player) {
                count++;
                r -= dir[0];
                c -= dir[1];
            }
            if (count >= 5) return true;
        }
        return false;
    }

    // 重置游戏
    public void resetGame() {
        board = new int[BOARD_SIZE][BOARD_SIZE];
        currentPlayer = 1;
        invalidate();
    }

    public interface EventListener {
        void onEvent(int player);
    }

    public void setOnTouchListener(EventListener listener) {
        this.touchListener = listener;
    }

    public void setOnGameEndListener(EventListener listener) {
        this.gameEndListener = listener;
    }

    public int getCurrentPlayer() {
        return currentPlayer;
    }

    public void setCurrentPlayer(int currentPlayer) {
        this.currentPlayer = currentPlayer;
    }

}